package com.wendy.thirdpartyaccess.qq;

import com.wendy.thirdpartyaccess.SocialConstants;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author zhuwending
 */
public class QQAuthenticationFilter extends AbstractAuthenticationProcessingFilter {


    public QQAuthenticationFilter(String defaultFilterProcessesUrl) {
        super(new AntPathRequestMatcher(defaultFilterProcessesUrl, "GET"));
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException {
        String code = request.getParameter(SocialConstants.CODE);
        String tokenAccessApi = String.format(SocialConstants.TOKEN_ACCESS_API, SocialConstants.ACCESS_TOKEN_URL, SocialConstants.GRANT_TYPE, SocialConstants.CLIENT_ID, SocialConstants.CLIENT_SECRET, code, SocialConstants.REDIRECT_URL);
        QQToken qqToken = this.getToken(tokenAccessApi);
        if (qqToken != null) {
            String openId = getOpenId(qqToken.getAccessToken());
            if (openId != null) {
                UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(qqToken.getAccessToken(), openId);
                return this.getAuthenticationManager().authenticate(authenticationToken);
            }
        }
        return null;
    }

    private QQToken getToken(String tokenAccessApi) throws IOException {
        Document document = Jsoup.connect(tokenAccessApi).get();
        String tokenResult = document.text();
        String[] results = tokenResult.split("&");
        if (results.length == 3) {
            QQToken qqToken = new QQToken();
            String accessToken = results[0].replace("access_token=", "");
            String expiresIn = results[1].replace("expires_in=", "");
            String refreshToken = results[2].replace("refresh_token=", "");
            qqToken.setAccessToken(accessToken);
            qqToken.setExpiresIn(Integer.valueOf(expiresIn));
            qqToken.setRefreshToken(refreshToken);
            return qqToken;
        }
        return null;
    }

    private String getOpenId(String accessToken) throws IOException {
        String url = SocialConstants.OPENID_URL + accessToken;
        Document document = Jsoup.connect(url).get();
        String resultText = document.text();
        String regex = "\"openid\":\"(.*?)\"";
        Matcher matcher = Pattern.compile(regex).matcher(resultText);
        if (matcher.find()) {
            return matcher.group(1);
        }
        return null;
    }
}
